from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect
from django.core.exceptions import ObjectDoesNotExist
import json
import datetime
import logging
import uuid

from pyfacture.timesheet import utils

from pyfacture import models
from pyfacture import message

logger = logging.getLogger(__name__)

class ContractDecoder(json.JSONDecoder):
    def decode(self, s):
        contract_dict = json.loads(s)
        contract = models.Contract()
        contract.name = contract_dict['name']
        contract.start = datetime.datetime.strptime(contract_dict['start'], '%d/%m/%Y')
        contract.end = datetime.datetime.strptime(contract_dict['end'], '%d/%m/%Y')
        contract.client = models.Client.objects.get(id=int(contract_dict['client_id']))
        contract.customer = models.Customer.objects.get(id=int(contract_dict['customer_id']))
        contract.hourly_rate = contract_dict['rate']
        logger.debug("Decoded contract " + str(contract))
        return contract

def new(request):
    if not request.user.is_authenticated():
        logger.info("user requested the new contract screen but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})

    logger.debug("Requested screen to create new contract")
    return render_to_response('new_contract.html', {
        'active_menu': 'contract',
        'active_submenu': 'new',
        'new_link': '/contract/new/',
        'view_link': '/contract/view/',
    })

def save(request):
    if not request.user.is_authenticated():
        logger.info("user requested to save a new contract but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})
    
    if request.is_ajax():
        try:
            contract = ContractDecoder().decode(request.raw_post_data)
            contract.save()
            logger.info("Saved new contract " + str(contract))
        except Exception, e:
            uid = uuid.uuid4()
            logger.error(message.msgWithUUID(uid, "Error saving contract " + contract.name),e)
            return message.buildError("Error saving contract", uid)
        redirect_url = "/contract/view/{0}/".format(contract.id)
        return HttpResponse('{"redirect":"' + redirect_url + '"}', 'application/json')

    redirect_url = "/contract/new/"
    return HttpResponse(redirect_url, 'text/html')

def view_default(request):
    logger.debug("User requested to view the default contract")
    if not request.user.is_authenticated():
        logger.info("user requested to view (default) contract but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})

    try:
        contract = models.Contract.objects.latest('id')
        logger.debug("The last contract is " + str(contract))
    except ObjectDoesNotExist:
        return new(request)
    return view(request,contract.id)

def view(request, contract_id):
    logger.debug("User requested to view contract with id " + str(contract_id))
    if not request.user.is_authenticated():
        logger.info("user requested to view contract with id " + str(contract_id) + " but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})
    
    selected_contract = models.Contract.objects.get(id=contract_id)
    logger.debug("Contract with id " + str(contract_id) + " found: " + str(selected_contract))

    try:
        all_contracts = list(models.Contract.objects.all())
    except models.Customer.DoesNotExist:
        all_contracts = []
        
    return render_to_response('view_contract.html', {
        'active_menu': 'contract',
        'active_submenu': 'view',
        'new_link': '/contract/new/',
        'view_link': '/contract/view/',
        'availableContracts': utils.getContractsForTemplate(all_contracts),
        'selected_contract': selected_contract.id,
        'start': selected_contract.start.strftime('%d/%m/%Y'),
        'end': selected_contract.end.strftime('%d/%m/%Y'),
        'client_name': selected_contract.client.name,
        'customer_name': selected_contract.customer.name,
        'rate': selected_contract.hourly_rate,
    })